﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WH.Common.Constant;

namespace WH.Common.Helper
{
    public static class Utils
    {
        /// <summary>
        /// 自动生成编号  201008251145409865
        /// </summary>
        /// <returns></returns>
        public static string CreateNo()
        {
            var random = new Random();
            var strRandom = random.Next(1000, 10000).ToString(); //生成编号
            var code = DateTime.Now.ToString("yyyyMMddHHmmss") + strRandom;//形如
            return code;
        }

        /// <summary>
        /// 去除对象string属性空白头和尾
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T TrimAll<T>(this T obj) where T : class, new()
        {
            if (obj is null)
            {
                return default;
            }
            var stringProperties = obj.GetType().GetProperties().Where(p => p.PropertyType == typeof(string));
            foreach (var stringProperty in stringProperties)
            {
                var val = stringProperty.GetValue(obj, null);

                if (val is null)
                {
                    continue;
                }

                var currentValue = val?.ToString();
                stringProperty.SetValue(obj, (currentValue ?? "").Trim(), null);
            }

            return obj;
        }

        /// <summary>
        /// 对象转字典
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Dictionary<string, string> ToDictionary<T>(this T obj, IDictionary<string, string>? dic = null) where T : class, new()
        {

            //return typeof(T).GetProperties().ToDictionary(p => p.Name, p => p.GetValue(obj)?.ToString() ?? "");

            var dics = new Dictionary<string, string>(dic ?? new Dictionary<string, string>()); //

            var t = obj.GetType(); // 获取对象对应的类， 对应的类型string

            var pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance); // 获取当前type公共属性io

            foreach (var p in pi)
            {
                var m = p.GetGetMethod();
                if (m is not null && m.IsPublic)
                {
                    var val = m.Invoke(obj, new object[] { });
                    // 进行判NULL处理
                    if (val is not null)
                    {
                        dics.Add(p.Name, val.ToString()); // 向字典添加元素
                    }
                }
            }
            return dics;
        }

        /// <summary>
        /// 对象转字典
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Dictionary<string, object> ToObjectDictionary<T>(this T obj) where T : class, new()
        {
            var dics = new Dictionary<string, object>(); //

            var t = obj.GetType(); // 获取对象对应的类， 对应的类型string

            var pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance); // 获取当前type公共属性io

            foreach (var p in pi)
            {
                if (p.PropertyType == typeof(object))
                {
                    var vals = p.GetValue(obj)?.ToObjectDictionary();

                    if (vals is not null)
                    {
                        foreach (var val in vals)
                        {
                            dics.Add($"{p.Name}_{val.Key}", val.Value); // 向字典添加元素 }
                        }
                    }
                }
                else
                {
                    var m = p.GetGetMethod();
                    if (m is not null && m.IsPublic)
                    {
                        var val = m.Invoke(obj, new object[] { });
                        // 进行判NULL处理
                        if (val is not null)
                        {
                            dics.Add(p.Name, val); // 向字典添加元素
                        }
                    }
                }
            }
            return dics;
        }

        /// <summary>
        /// 字符串枚举列表类型转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns></returns>
        public static List<T>? ParseEnum<T>(this string str) where T : Enum
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                return default;
            }

            List<T> list = str.Split(',').Select(t =>
            {
                try
                {
                    return (T?)Enum.Parse(typeof(T), t.FirstCharToUpper());
                }
                catch
                {
                    return default;
                }
            }).Where(x => x is not null).Cast<T>().ToList();

            return list;
        }

        /// <summary>
        /// 字符串首字母转大写
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string FirstCharToUpper(this string str)
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                return str;
            }

            if (str.Length == 1)
            {
                return str.ToUpper();
            }

            return char.ToUpper(str[0]) + str.Substring(1);
        }

        /// <summary>
        /// 字符串首字母转小写写
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string FirstCharToLower(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return str;

            char[] chars = str.ToCharArray();
            chars[0] = char.ToLower(chars[0]);
            return new string(chars);
        }
        /// <summary>
        /// 数字转汉字
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static string ConvertToChineseSingle(this int number)
        {
            if (number < 0 || number > 9)
            {
                return "";
            }

            string[] chineseNumbers = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
            return chineseNumbers[number];
        }

        public static string ConvertToChinese(this int number)
        {
            StringBuilder sb = new StringBuilder();
            while (number > 0)
            {
                int digit = number % 10;
                sb.Insert(0, ConvertToChineseSingle(digit));
                number /= 10;
            }
            return sb.ToString();
        }

        public static IEnumerable<T> KeywordWhere<T>(this IEnumerable<T> list, string keyword, int equals = 0, List<string>? Fields = default) where T : class, new()
        {
            if (string.IsNullOrWhiteSpace(keyword))
            {
                return list;
            }

            list = list.Where(item =>
            {
                var dics = ToObjectDictionary(item) as Dictionary<string, object> ?? new Dictionary<string, object>();

                bool flags = true;

                if (Fields is not null)
                {
                    dics = dics.Where(d => Fields.Contains(d.Key)).ToDictionary(x => x.Key, x => x.Value);
                }

                foreach (var dic in dics)
                {
                    var val = dic.Value?.ToString();
                    if (equals == 1)
                    {
                        if (val?.Equals(keyword) == true)
                        {
                            return true;
                        }
                    }
                    else
                    {
                        if (val?.Contains(keyword) == true)
                        {
                            return true;
                        }
                    }
                }

                //var arr = filter.Value?.ToString()?.Split('|');

                //if (arr is not null && arr.Length > 0)
                //{
                //    var val = dics[filter.Key]?.ToString()?.ToLower() ?? string.Empty;
                //    var filterVal = filter.Value?.ToString()?.ToLower() ?? string.Empty;

                //    if (arr.Length > 1 && arr[1] == "1")
                //    {
                //        if (val.Equals(filterVal) == false)
                //        {
                //            return false;
                //        }
                //    }
                //    else
                //    {
                //        if (val.Contains(filterVal) == false)
                //        {
                //            return false;
                //        }
                //    }
                //}

                return false;
            });

            return list;
        }

        public static IEnumerable<T> Where<T>(this IEnumerable<T> list, List<string> keywords) where T : class, new()
        {
            foreach (var keyword in keywords)
            {
                list = list.KeywordWhere(keyword);
            }

            return list;
        }

        public static string GetKeywordsFilter(string keyword, int equals = 0)
        {
            return $"{string.Join(',', BusinessFunction.KeywordFields)}|{keyword}|{equals}";
        }

        public static IEnumerable<T> Where<T>(this IEnumerable<T> list, Dictionary<string, object> filters) where T : class, new()
        {

            list = list.Where(item =>
            {
                var dics = ToObjectDictionary(item) as Dictionary<string, object> ?? new Dictionary<string, object>();

                bool flags = true;

                foreach (var filter in filters)
                {
                    // 判断对象的属性是否满足筛选条件
                    var p = dics.ContainsKey(filter.Key);

                    if (p == true)
                    {
                        var arr = filter.Value?.ToString()?.Split('|');

                        if (arr is not null && arr.Length > 0)
                        {
                            var val = dics[filter.Key]?.ToString();
                            var filterVal = filter.Value?.ToString();

                            if (arr.Length > 1 && arr[1] == "1")
                            {
                                if (val is null || val.Equals(filterVal, StringComparison.OrdinalIgnoreCase) == false)
                                {
                                    flags = flags && false;
                                }
                            }
                            else
                            {
                                if (string.IsNullOrWhiteSpace(filterVal) == false && val?.Contains(filterVal, StringComparison.OrdinalIgnoreCase) == false)
                                {
                                    flags = flags && false;
                                }
                            }
                        }

                    }
                    else
                    {
                        return false;
                    }
                    //else//不存在可能是关键字
                    //{
                    //    var arr = filter.Value?.ToString()?.Split('|');

                    //    if (arr is not null && arr.Length > 1)
                    //    {
                    //        var fields = arr.First().Split(',');

                    //        foreach (var field in fields)
                    //        {
                    //            var fp = dics.ContainsKey(field);

                    //            if (fp == false)
                    //            {
                    //                continue;
                    //            }

                    //            var val = dics[field]?.ToString()?.ToLower() ?? string.Empty;
                    //            var filterVal = arr[1];

                    //            if (arr.Length > 2 && arr[2] == "1")
                    //            {
                    //                if (val.Equals(filterVal) == true)
                    //                {
                    //                    return true;
                    //                }
                    //            }
                    //            else
                    //            {
                    //                if (val.Contains(filterVal) == true)
                    //                {
                    //                    return true;
                    //                }
                    //            }
                    //        }

                    //        return false;
                    //    }

                    //}
                }
                return flags;
            });

            return list;
        }

        public static object? GetValue(this object obj, string field)
        {
            // 获取 Name 字段的值
            var p = obj.GetType().GetProperty(field);

            var value = p?.GetValue(obj);

            return value;
        }
        /// <summary>
        /// 对象转INT
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int ObjToInt(object str)
        {
            try
            {
                string str2 = str.ToString();
                return int.Parse(str2);
            }
            catch
            {
                return 0;
            }
        }
        public static DateTime ConvertUnixTimeStampToDateTime(double unixTimeStamp)
        {
            // Unix时间戳是从1970年1月1日00:00:00开始的时间秒数
            System.DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            dateTime = dateTime.AddSeconds(unixTimeStamp).ToLocalTime();
            return dateTime;
        }
    }
}